//Fusion of the 422 Proportion
//Dustin Striplin, Tyler Simrell, Lawrence Grass, and Jacob Hall
//Finished 5/1/13

package view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.LinkedList;

import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JRadioButton;
import javax.swing.JTextField;

import model.DataGatherer;
import model.SetupInfo;
import controller.MainController;

/**
 * The FormPanel class for the webcrawler program
 * @author Lawrence Grass, Tyler Simrell
 * @version 4/28/13
 */
@SuppressWarnings("serial")
public class FormPanel extends JPanel
					   implements ActionListener {
	
	private HashMap<String, Integer> keywordList = new HashMap<String, Integer>();
	
	private MainController controller;
	
	private DataGatherer data;
	
	private ReporterView parent;
	
	private JTextField seed;
	
	private ButtonGroup threadGroup;
	
	private JTextField maxParsers;
	
	private JTextField maxRetrievers;
	
	private JTextField maxPagesToRetrieve;
	
	private SetupInfo setupOptions;
	
	JProgressBar progressBar;
	
	private boolean multiThreaded = true;
	
	/**
	 * Creates a new Form panel
	 * @param controller
	 */
	public FormPanel(MainController controller, ReporterView parent){
		this.setPreferredSize(new Dimension(400, 640));
		this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		this.controller = controller;
		this.parent = parent;
		
		//sets up a title
		JPanel titlePanel = new JPanel();
		JLabel title = new JLabel("Options");
		titlePanel.add(title);
		this.add(titlePanel);
		
		//sets up the seed option		
		this.add(seedOptions());
		
		//sets up the thread chooser
		this.add(threadOptions());
		
		//sets up the max Parsers/Retrievers options
		this.add(parserRetrieverOptions());
		
		//sets up the max number of pages to retrieve option
		this.add(maxPagesToRetrieveOption());
		
		//keyword chooser panel
		KeywordDisplay kwdsply = new KeywordDisplay();
		this.add(kwdsply);
		
		JPanel submit = new JPanel();
		JButton submitButton = new JButton("Start");
		submitButton.setActionCommand("Start");
		submitButton.addActionListener(this);
		submit.add(submitButton);
		this.add(submit);
	}
	
	private void setUpProgressBar(){
		if(progressBar != null) this.remove(progressBar);
		progressBar = new JProgressBar(0, 100);
		progressBar.setValue(0);
		progressBar.setStringPainted(true);
		progressBar.setForeground(Color.GREEN);
		this.add(progressBar);
		this.revalidate();
	}
	
	/**
	 * Method is called for updating the progress bar with the most up-to-date estimation
	 * of the percentage of work that has been fully accomplished by the web-crawler program
	 */
	public void updateProgress()
	{
		
		int temp = 100 * controller.getNumPagesRetrieved() / controller.getPageLimit();
		if (temp == 100)
		{
			//this prints the data to file when the program is basically 100% done.
			//There is no guarantee that this won't be called 2 or 3 times while
			//processing 1000-10000 pages because those numbers loose their 
			//precision when dividing into an int value.  However, this is a rough
			//estimate as to being almost done.  If the file is printed a few times,
			//the most up-to-date info is being written with no loss of prior data
			//and little expense to the total run-time.
			controller.printDataToFile();
		}
		progressBar.setValue(temp);
	}
	
	/**
	 * @return the seed options panel
	 */
	private JPanel seedOptions(){
		JPanel seedRow = new JPanel(new BorderLayout());
		seedRow.setMaximumSize(new Dimension(380, 40));
		seed = new JTextField("http://faculty.washington.edu/gmobus/", 100);
		JLabel seedLabel = new JLabel("Seed: ");
		seedRow.add(seedLabel, BorderLayout.WEST);
		seedRow.add(seed, BorderLayout.CENTER);
		return seedRow;
	}
	
	/**
	 * @return the threading options panel
	 */
	private JPanel threadOptions(){
		JPanel threadChooser = new JPanel();
		threadChooser.setMaximumSize(new Dimension(400, 40));
		threadGroup = new ButtonGroup();
		JRadioButton singleThreaded = new JRadioButton("Single Threaded");
		singleThreaded.setActionCommand("single");
		singleThreaded.addActionListener(this);
		threadGroup.add(singleThreaded);
		threadChooser.add(singleThreaded);
		JRadioButton multiThreaded = new JRadioButton("Multi Threaded");
		multiThreaded.setActionCommand("multi");
		multiThreaded.addActionListener(this);
		threadGroup.add(multiThreaded);
		multiThreaded.setSelected(true);
		threadChooser.add(multiThreaded);
		return threadChooser;
	}
	
	/**
	 * @return the max number of pages to retrieve panel
	 */
	private JPanel maxPagesToRetrieveOption(){
		JPanel maxPagesChooser = new JPanel();
		maxPagesChooser.setMaximumSize(new Dimension(400, 40));
		maxPagesToRetrieve = new JTextField(5);
		maxPagesToRetrieve.setText("1");
		JLabel maxPagesToRetrieveLabel = new JLabel ("Maximum number of pages to retrieve: ");
		maxPagesChooser.add(maxPagesToRetrieveLabel);
		maxPagesChooser.add(maxPagesToRetrieve);
		return maxPagesChooser;
	}
	
	/**
	 * @return the max parsers and max retrievers panel
	 */
	private JPanel parserRetrieverOptions(){
		JPanel parsersRetrievers = new JPanel();
		parsersRetrievers.setMaximumSize(new Dimension(400, 40));
		maxParsers = new JTextField(3);
		maxParsers.setText("1");
		JLabel maxParsersLabel = new JLabel("Max Parsers: ");
		parsersRetrievers.add(maxParsersLabel);
		parsersRetrievers.add(maxParsers);
		maxRetrievers = new JTextField(3);
		maxRetrievers.setText("1");
		JLabel maxRetrieversLabel = new JLabel("Max Retrievers: ");
		parsersRetrievers.add(maxRetrieversLabel);
		parsersRetrievers.add(maxRetrievers);
		return parsersRetrievers;
	}
	
	@Override
	public void actionPerformed(ActionEvent e){
		
		//the listener for the threaded buttons
		if(e.getActionCommand().equals("single"))
		{
			multiThreaded = false;
		}
		
		else if (e.getActionCommand().equals("multi"))
		{
			multiThreaded = true;
		}
		
		//the listener for the start button
		else if(e.getActionCommand().equals("Start"))
		{
			data = new DataGatherer();
			parent.resetCurrentResults();
			setUpProgressBar();
			int maxPars = Integer.parseInt(maxParsers.getText());
			int maxRetrs = Integer.parseInt(maxRetrievers.getText());
			int maxPages = Integer.parseInt(maxPagesToRetrieve.getText());
			if (maxPages > SetupInfo.ABSOLUTE_PAGE_LIMIT)
			{
				JOptionPane.showMessageDialog(null,  "The maximum number of pages to search" +
						"allowed is " + SetupInfo.ABSOLUTE_PAGE_LIMIT + ".  Program defaulted to that value.");
				maxPagesToRetrieve.setText(String.valueOf(SetupInfo.ABSOLUTE_PAGE_LIMIT));
			}
			setupOptions = new SetupInfo(seed.getText(), keywordList, maxPars, maxRetrs, maxPages, multiThreaded);
			controller.startButton(setupOptions, data);
		}
	}
	
	/**
	 * A private class to take care of the keyword panel, including event handling.
	 */
	private class KeywordDisplay extends JPanel
								 implements ActionListener{
		
		private JButton addKeyword;
		
		private JTextField keyword;
		
		private JPanel keywordDisplay;
		
		private LinkedList<JButton> keywords = new LinkedList<JButton>();
		
		public KeywordDisplay(){
			this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
			
			JPanel keywordChooser = new JPanel();
			keywordChooser.setMaximumSize(new Dimension(400, 40));
			JLabel keywordLabel = new JLabel("Keyword: ");
			keyword = new JTextField(15);
			addKeyword = new JButton("Add");
			addKeyword.addActionListener(this);
			keywordChooser.add(keywordLabel);
			keywordChooser.add(keyword);
			keywordChooser.add(addKeyword);
			this.add(keywordChooser);
			
			String inst = "Click a keyword button below to remove it:";
			JPanel instructionPanel = new JPanel();
			instructionPanel.setMaximumSize(new Dimension(400, 40));
			JLabel instructions = new JLabel(inst);
			instructionPanel.add(instructions);
			this.add(instructionPanel);
			
			//keyword panel
			keywordDisplay = new JPanel();
			keywordDisplay.setLayout(new BoxLayout(keywordDisplay, BoxLayout.Y_AXIS));
			this.add(keywordDisplay);
		}
		@Override
		public void actionPerformed(ActionEvent e){
			JButton source = (JButton) e.getSource();
			System.out.println(source.getText());
			//the listener for the add button
			if(source.getText().equals("Add")){
				String text = keyword.getText();
				if(keyword.getText().equals("")){
					keyword.setText("please type a keyword");
				}else{
					text.trim();
					JButton button = new JButton(text);
					button.addActionListener(this);
					keywords.add(button);
					keywordList.put(text, 0); //info for the SetupInfo object
					keyword.setText("");
				}
			//the listener to remove items from the keyword list
			}else{
				String buttonToRemove = source.getText();
				keywords.remove(source);
				keywordList.remove(buttonToRemove);
				keywordDisplay.revalidate();
			}
			keywordDisplay.removeAll();
			for(JButton word: keywords){
				keywordDisplay.add(word);
				System.out.println("keyword: " + word.getText());
			}
			keywordDisplay.revalidate();
		}
	}
}